#!/usr/bin/python3
# -*- encoding:utf-8 -*-
# author: king
# create date time: 2024/4/14 下午1:12

"""
策略模式（Stategy）：它定义了算法家族，分别封装起来，让他们之间可以相互替换，此模式让算法的变化不会影响到使用算法的客户。
常与工厂模式结合
"""
import decimal
import os
import sys
import abc
from decimal import Decimal
from enum import Enum, unique

from loguru import logger


class CashSuper(metaclass=abc.ABCMeta):
    def format_money(self, str_number):
        """
        将字符串格式的金额，转化成 decimal 类型，并保留两位小数
        :return:
        :author: king
        :create date time: 2024/4/14 下午1:14
        """
        return Decimal(str_number).quantize(Decimal('0.00'))

    @abc.abstractmethod
    def accept_cash(self, money):
        pass


@unique
class CashTypeEnum(Enum):
    """
    收费打折类型
    """
    normal = '正常收费'
    sale_300_back_100 = '满300返100'
    sale_8 = '打八折'


class CashNormal(CashSuper):
    """
    正常收费
    """

    def accept_cash(self, money):
        return self.format_money(money)


class CashRebate(CashSuper):
    """
    打折收费
    """

    def __init__(self, money_ra_bate=1):
        self.money_ra_bate = self.format_money(money_ra_bate)  # 打折率

    def accept_cash(self, money):
        return self.format_money(money) * self.money_ra_bate


class CashReturn(CashSuper):
    """
    返利收费
    """

    def __init__(self, money_condition, money_return):
        self.money_condition = self.format_money(money_condition)
        self.money_return = self.format_money(money_return)

    def accept_cash(self, money):
        money = self.format_money(money)
        if money > self.money_condition:
            money -= money / self.money_condition * self.money_return
        return self.format_money(money)


class CashFactory(object):
    """
    现金收费类-工厂模式
    """

    def create_cash_accept(self, type):
        """
        :return:
        :author: king
        :create date time: 2024/4/14 下午1:25
        """
        if type == CashTypeEnum.normal.value:
            cs = CashNormal()
        elif type == CashTypeEnum.sale_300_back_100.value:
            cs = CashReturn(300, 100)
        elif type == CashTypeEnum.sale_8.value:
            cs = CashRebate(0.8)
        else:
            logger.error(f"不知道的类型, {type}")
            return
        return cs


def main():
    """ 程序入口 """
    cf = CashFactory()
    cs = cf.create_cash_accept(type='满300返100')
    logger.info(cs.accept_cash(1000))


if __name__ == "__main__":
    main()
